@page "/chat-app"
@using CodeSpirit.Core
@using CodeSpirit.Messaging.Models
@using CodeSpirit.Web.Services
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.SignalR.Client
@using Microsoft.JSInterop
@inject NavigationManager NavigationManager
@inject IJSRuntime JSRuntime
@inject IHttpContextAccessor HttpContextAccessor
@inject IJwtAuthService AuthService
@implements IAsyncDisposable

<div class="chat-container">
    <div class="chat-sidebar">
        <div class="user-info">
            <div class="avatar">@_username?.Substring(0, 1).ToUpper()</div>
            <div class="username">@_username</div>
        </div>
        
        <div class="conversation-list">
            <div class="list-header">
                <h3>对话列表</h3>
                <button class="new-chat-btn" @onclick="ShowNewChatDialog">
                    <i class="icon-plus"></i>
                </button>
            </div>
            
            @if (Conversations == null)
            {
                <div class="loading">加载中...</div>
            }
            else if (!Conversations.Any())
            {
                <div class="empty-state">
                    <p>暂无对话</p>
                    <button class="start-chat-btn" @onclick="ShowNewChatDialog">开始聊天</button>
                </div>
            }
            else
            {
                @foreach (var conversation in Conversations)
                {
                    <div class="conversation-item @(SelectedConversation?.Id == conversation.Id ? "active" : "")"
                         @onclick="() => SelectConversation(conversation)">
                        <div class="conversation-avatar">
                            @conversation.Title?.Substring(0, 1).ToUpper()
                        </div>
                        <div class="conversation-info">
                            <div class="conversation-title">@conversation.Title</div>
                            <div class="conversation-preview">
                                @(conversation.Messages.Any() ? 
                                    (conversation.Messages.OrderByDescending(m => m.CreatedAt).First().Content.Length > 20 ? 
                                        conversation.Messages.OrderByDescending(m => m.CreatedAt).First().Content.Substring(0, 20) + "..." : 
                                        conversation.Messages.OrderByDescending(m => m.CreatedAt).First().Content) : 
                                    "无消息")
                            </div>
                        </div>
                        @if (GetUnreadCount(conversation) > 0)
                        {
                            <div class="unread-badge">@GetUnreadCount(conversation)</div>
                        }
                    </div>
                }
            }
        </div>
    </div>
    
    <div class="chat-main">
        @if (SelectedConversation == null)
        {
            <div class="empty-chat">
                <div class="empty-chat-content">
                    <h2>选择一个对话或开始新的对话</h2>
                    <button class="start-chat-btn" @onclick="ShowNewChatDialog">开始新的对话</button>
                </div>
            </div>
        }
        else
        {
            <div class="chat-header">
                <h2>@SelectedConversation.Title</h2>
                <div class="chat-actions">
                    <button class="action-btn" @onclick="ShowParticipantsDialog">
                        <i class="icon-users"></i>
                    </button>
                </div>
            </div>
            
            <div class="chat-messages" @ref="messagesContainer">
                @if (Messages == null)
                {
                    <div class="loading">加载消息中...</div>
                }
                else if (!Messages.Any())
                {
                    <div class="empty-messages">
                        <p>暂无消息</p>
                    </div>
                }
                else
                {
                    @foreach (var message in Messages)
                    {
                        <div class="message @(message.SenderId == _userId ? "message-sent" : "message-received")">
                            <div class="message-avatar">
                                @message.SenderName?.Substring(0, 1).ToUpper()
                            </div>
                            <div class="message-content">
                                <div class="message-sender">@message.SenderName</div>
                                <div class="message-text">@message.Content</div>
                                <div class="message-time">@message.CreatedAt.ToString("yyyy-MM-dd HH:mm")</div>
                            </div>
                        </div>
                    }
                }
            </div>
            
            <div class="chat-input">
                <textarea 
                    @bind="NewMessage" 
                    @bind:event="oninput" 
                    @onkeydown="HandleKeyDown"
                    placeholder="输入消息..." 
                    rows="3"></textarea>
                <button class="send-btn" @onclick="SendMessage" disabled="@string.IsNullOrWhiteSpace(NewMessage)">
                    <i class="icon-send"></i>
                </button>
            </div>
        }
    </div>
</div>

@if (ShowNewChat)
{
    <div class="modal-overlay">
        <div class="modal-dialog">
            <div class="modal-header">
                <h3>新建对话</h3>
                <button class="close-btn" @onclick="() => ShowNewChat = false">
                    <i class="icon-close"></i>
                </button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="chat-title">对话标题</label>
                    <input id="chat-title" type="text" @bind="NewChatTitle" placeholder="输入对话标题" />
                </div>
                <div class="form-group">
                    <label for="participants">参与者</label>
                    <select id="participants" multiple @bind="SelectedParticipants">
                        @foreach (var user in AvailableUsers)
                        {
                            <option value="@user.UserId">@user.UserName</option>
                        }
                    </select>
                </div>
            </div>
            <div class="modal-footer">
                <button class="cancel-btn" @onclick="() => ShowNewChat = false">取消</button>
                <button class="create-btn" @onclick="CreateNewChat" disabled="@(string.IsNullOrWhiteSpace(NewChatTitle) || !SelectedParticipants.Any())">
                    创建
                </button>
            </div>
        </div>
    </div>
}

@if (ShowParticipants)
{
    <div class="modal-overlay">
        <div class="modal-dialog">
            <div class="modal-header">
                <h3>对话参与者</h3>
                <button class="close-btn" @onclick="() => ShowParticipants = false">
                    <i class="icon-close"></i>
                </button>
            </div>
            <div class="modal-body">
                <div class="participants-list">
                    @foreach (var participant in SelectedConversation.Participants.Where(p => !p.HasLeft))
                    {
                        <div class="participant-item">
                            <div class="participant-avatar">
                                @participant.UserName?.Substring(0, 1).ToUpper()
                            </div>
                            <div class="participant-name">@participant.UserName</div>
                            @if (participant.UserId != _userId)
                            {
                                <button class="remove-btn" @onclick="() => RemoveParticipant(participant.UserId)">
                                    <i class="icon-remove"></i>
                                </button>
                            }
                        </div>
                    }
                </div>
                <div class="add-participant">
                    <h4>添加新参与者</h4>
                    <div class="form-group">
                        <select @bind="NewParticipantId">
                            <option value="">选择用户</option>
                            @foreach (var user in AvailableUsers.Where(u => !SelectedConversation.Participants.Any(p => p.UserId == u.UserId && !p.HasLeft)))
                            {
                                <option value="@user.UserId">@user.UserName</option>
                            }
                        </select>
                        <button class="add-btn" @onclick="AddParticipant" disabled="@string.IsNullOrEmpty(NewParticipantId)">
                            添加
                        </button>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button class="close-btn" @onclick="() => ShowParticipants = false">关闭</button>
            </div>
        </div>
    </div>
}

@code {
    private HubConnection hubConnection;
    private ElementReference messagesContainer;
    private List<Conversation> Conversations { get; set; }
    private Conversation SelectedConversation { get; set; }
    private List<Message> Messages { get; set; }
    private string NewMessage { get; set; }
    private bool ShowNewChat { get; set; }
    private bool ShowParticipants { get; set; }
    private string NewChatTitle { get; set; }
    private List<string> SelectedParticipants { get; set; } = new();
    private string NewParticipantId { get; set; }
    private string _userId;
    private string _username;
    private Dictionary<string, bool> _welcomeMessageShown = new();
    
    // 模拟可用用户列表，实际应从用户服务获取
    private List<UserInfo> AvailableUsers { get; set; } = new List<UserInfo>
    {
        new UserInfo { UserId = "user2", UserName = "李四" },
        new UserInfo { UserId = "user3", UserName = "王五" },
        new UserInfo { UserId = "user4", UserName = "赵六" },
        new UserInfo { UserId = "user5", UserName = "钱七" }
    };

    protected override async Task OnInitializedAsync()
    {
        // 避免在预渲染时设置过多状态
        if (_isPrerendering)
        {
            return;
        }
        
        // 初始化数据结构，避免空引用
        Conversations = new List<Conversation>();
        Messages = new List<Message>();
        
        // 获取用户信息
        _userId = await AuthService.GetUserIdAsync();
        _username = await AuthService.GetUsernameAsync();
        
        if (string.IsNullOrEmpty(_userId))
        {
            // 未登录用户跳转到登录页
            NavigationManager.NavigateTo("/login", forceLoad: false);
            return;
        }
    }
    
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            if (_isPrerendering)
            {
                return;
            }
            
            try 
            {
                // 清理DOM中的无效属性
                await JSRuntime.InvokeVoidAsync("cleanupInvalidAttributes");
                
                // 客户端初始化时连接 SignalR
                await InitializeSignalRConnection();
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"初始化失败: {ex.Message}");
            }
        }
    }
    
    private async Task InitializeSignalRConnection()
    {
        try
        {
            // 初始化 HubConnection
            hubConnection = new HubConnectionBuilder()
                .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
                .WithAutomaticReconnect()
                .Build();

            // 注册所有事件处理程序
            RegisterHubHandlers();
            
            // 开始连接
            await hubConnection.StartAsync();
            
            // 连接成功后加载对话
            if (hubConnection.State == HubConnectionState.Connected)
            {
                await LoadConversations();
                
                // 使用InvokeAsync确保方法在UI线程上异步执行
                // 延迟显示欢迎消息，确保UI和JS完全初始化
                await InvokeAsync(async () => {
                    await Task.Delay(500);
                    await ShowInitialWelcomeToast();
                });
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"初始化SignalR连接时出错: {ex.Message}");
        }
    }
    
    // 添加一个标志指示是否在预渲染
    private bool _isPrerendering => 
        HttpContextAccessor?.HttpContext != null &&
        !HttpContextAccessor.HttpContext.Response.HasStarted;

    // 添加显示欢迎消息的方法
    private void ShowWelcomeMessage()
    {
        if (SelectedConversation == null || Messages == null)
            return;
        
        // 检查是否已经为当前对话显示过欢迎消息
        if (_welcomeMessageShown.TryGetValue(SelectedConversation.Id.ToString(), out bool shown) && shown)
            return;
            
        // 创建一个系统欢迎消息
        var welcomeMessage = new Message
        {
            Id = Guid.NewGuid(),
            Content = $"欢迎加入 \"{SelectedConversation.Title}\" 对话！",
            SenderId = "system",
            SenderName = "系统消息",
            Type = MessageType.SystemNotification,
            CreatedAt = DateTime.Now
        };

        // 将欢迎消息添加到消息列表
        Messages.Add(welcomeMessage);
        
        // 标记已为此对话显示欢迎消息
        _welcomeMessageShown[SelectedConversation.Id.ToString()] = true;
        
        StateHasChanged();
        
        // 滚动到底部显示欢迎消息
        InvokeAsync(() => ScrollToBottom());
    }

    // 修改显示欢迎消息的方法，添加错误处理
    private async Task ShowInitialWelcomeToast()
    {
        try 
        {
            // 等待一小段时间，确保JS已加载
            await Task.Delay(300);
            
            // 调用 JS 方法显示欢迎消息
            await JSRuntime.InvokeVoidAsync("showToast", $"欢迎回来，{_username}！", "系统消息");
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"显示欢迎通知失败: {ex.Message}");
        }
    }

    private void RegisterHubHandlers()
    {
        hubConnection.On<Message>("ReceiveMessage", async (message) =>
        {
            // 使用 InvokeAsync 在 UI 线程上更新状态
            await InvokeAsync(() => {
                if (SelectedConversation != null && message.SenderId != _userId)
                {
                    Messages.Add(message);
                    StateHasChanged();
                    _ = ScrollToBottom();
                }
                
                // 无论是否当前对话，都显示通知（除非消息是自己发送的）
                if (message.SenderId != _userId)
                {
                    try 
                    {
                        // 使用admin.js中定义的通知函数
                        var conversationId = SelectedConversation?.Id.ToString() ?? string.Empty;
                        JSRuntime.InvokeVoidAsync(
                            "showChatNotification", 
                            message.Content, 
                            message.SenderName, 
                            conversationId);
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine($"显示通知失败: {ex.Message}");
                    }
                }
            });
        });

        hubConnection.On<List<Message>, int>("ReceiveHistory", async (messages, totalCount) =>
        {
            // 使用 InvokeAsync 在 UI 线程上更新状态
            await InvokeAsync(() => {
                Messages = messages;
                StateHasChanged();
                _ = ScrollToBottom();
                
                // 消息历史记录加载后显示欢迎消息
                ShowWelcomeMessage();
            });
        });

        hubConnection.On<List<Conversation>>("ReceiveConversations", async (conversations) =>
        {
            // 使用 InvokeAsync 在 UI 线程上更新状态
            await InvokeAsync(() => {
                Conversations = conversations;
                StateHasChanged();
            });
        });

        hubConnection.On<Conversation>("ConversationCreated", async (conversation) =>
        {
            // 使用 InvokeAsync 在 UI 线程上更新状态
            await InvokeAsync(() => {
                Conversations.Add(conversation);
                SelectedConversation = conversation;
                Messages = new List<Message>();
                
                // 确保为新创建的对话显示欢迎消息
                if (_welcomeMessageShown.ContainsKey(conversation.Id.ToString()))
                {
                    _welcomeMessageShown[conversation.Id.ToString()] = false;
                }
                
                StateHasChanged();
            });
        });

        hubConnection.On<Conversation>("NewConversation", async (conversation) =>
        {
            // 使用 InvokeAsync 在 UI 线程上更新状态
            await InvokeAsync(() => {
                Conversations.Add(conversation);
                
                // 确保为新加入的对话显示欢迎消息
                if (_welcomeMessageShown.ContainsKey(conversation.Id.ToString()))
                {
                    _welcomeMessageShown[conversation.Id.ToString()] = false;
                }
                
                StateHasChanged();
            });
        });

        hubConnection.On<string>("Error", (errorMessage) =>
        {
            // 处理错误
            Console.WriteLine($"Error: {errorMessage}");
        });
    }

    private async Task LoadConversations()
    {
        try
        {
            if (hubConnection?.State == HubConnectionState.Connected)
            {
                await hubConnection.SendAsync("GetUserConversations", _userId);
                
                // 加载完会话后，更新未读消息计数
                await UpdateUnreadMessageCount();
            }
            else
            {
                Console.Error.WriteLine("无法加载对话，SignalR连接未建立");
                // 这里可以添加重试逻辑或通知用户
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"加载对话时出错: {ex.Message}");
        }
    }
    
    // 更新未读消息数量，用于顶部导航栏显示
    private async Task UpdateUnreadMessageCount()
    {
        try
        {
            if (string.IsNullOrEmpty(_userId))
                return;
                
            // 调用 JS 方法更新未读消息数
            await JSRuntime.InvokeVoidAsync("fetchUnreadNotificationCount", _userId);
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"更新未读消息计数失败: {ex.Message}");
            // 捕获所有异常
        }
    }

    private async Task SelectConversation(Conversation conversation)
    {
        SelectedConversation = conversation;
        Messages = null;
        
        try
        {
            if (hubConnection?.State == HubConnectionState.Connected)
            {
                await hubConnection.SendAsync("JoinConversation", conversation.Id);
                await hubConnection.SendAsync("GetMessageHistory", conversation.Id);
                
                // ReceiveHistory事件处理程序将显示欢迎消息
            }
            else
            {
                Console.Error.WriteLine("无法选择对话，SignalR连接未建立");
                // 尝试重新连接
                await TryReconnectAsync();
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"选择对话时出错: {ex.Message}");
        }
    }

    private async Task SendMessage()
    {
        if (string.IsNullOrWhiteSpace(NewMessage))
            return;

        if (SelectedConversation == null)
            return;

        try
        {
            if (hubConnection?.State == HubConnectionState.Connected)
            {
                var message = new Message
                {
                    Id = Guid.NewGuid(),
                    Content = NewMessage,
                    SenderId = _userId,
                    SenderName = _username,
                    Type = MessageType.UserMessage,
                    CreatedAt = DateTime.Now
                };

                await hubConnection.SendAsync("SendMessage", message, SelectedConversation.Id);
                NewMessage = string.Empty;
            }
            else
            {
                Console.Error.WriteLine("无法发送消息，SignalR连接未建立");
                // 尝试重新连接
                await TryReconnectAsync();
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"发送消息时出错: {ex.Message}");
        }
    }

    private async Task HandleKeyDown(KeyboardEventArgs e)
    {
        if (e.Key == "Enter" && !e.ShiftKey)
        {
            await SendMessage();
        }
    }

    private void ShowNewChatDialog()
    {
        try
        {
            NewChatTitle = string.Empty;
            SelectedParticipants = new List<string>();
            ShowNewChat = true;
            StateHasChanged();
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"显示新对话对话框失败: {ex.Message}");
        }
    }

    private async Task CreateNewChat()
    {
        if (string.IsNullOrWhiteSpace(NewChatTitle) || !SelectedParticipants.Any())
            return;

        try
        {
            if (hubConnection?.State == HubConnectionState.Connected)
            {
                // 添加当前用户到参与者列表
                var participants = new List<string>(SelectedParticipants)
                {
                    _userId
                };

                // 修改调用，包含所有必要的参数
                await hubConnection.SendAsync("CreateConversation", NewChatTitle, _userId, _username, participants);
                
                // 重置表单
                NewChatTitle = string.Empty;
                SelectedParticipants.Clear();
                ShowNewChat = false;
            }
            else
            {
                Console.Error.WriteLine("无法创建新对话，SignalR连接未建立");
                // 尝试重新连接
                await TryReconnectAsync();
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"创建新对话时出错: {ex.Message}");
        }
    }

    private void ShowParticipantsDialog()
    {
        if (SelectedConversation == null)
            return;

        NewParticipantId = string.Empty;
        ShowParticipants = true;
        StateHasChanged();
    }

    private async Task AddParticipant()
    {
        if (string.IsNullOrEmpty(NewParticipantId) || SelectedConversation == null)
            return;

        var user = AvailableUsers.FirstOrDefault(u => u.UserId == NewParticipantId);
        if (user == null)
            return;

        if (hubConnection.State == HubConnectionState.Connected)
        {
            await hubConnection.SendAsync("AddUserToConversation", SelectedConversation.Id, user.UserId, user.UserName);
            NewParticipantId = string.Empty;
        }
    }

    private async Task RemoveParticipant(string userId)
    {
        if (string.IsNullOrEmpty(userId) || SelectedConversation == null)
            return;

        if (hubConnection.State == HubConnectionState.Connected)
        {
            await hubConnection.SendAsync("RemoveUserFromConversation", SelectedConversation.Id, userId);
        }
    }

    private int GetUnreadCount(Conversation conversation)
    {
        // 由于Message类不再有IsRead属性，该属性已被移动到UserMessageRead类
        // 实际应用中应从服务器获取未读消息数
        // 临时返回0，应改为调用消息服务API获取
        return 0;
    }

    private async Task ScrollToBottom()
    {
        try 
        {
            await Task.Delay(50); // 等待DOM更新
            if (messagesContainer.Context != null)
            {
                await JSRuntime.InvokeVoidAsync("scrollToBottom", messagesContainer);
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"滚动到底部失败: {ex.Message}");
            // 捕获异常，避免中断电路
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (hubConnection != null)
        {
            await hubConnection.DisposeAsync();
        }
        
        // 不再需要释放JS模块
    }

    // 添加一个重连方法
    private async Task TryReconnectAsync()
    {
        try
        {
            if (hubConnection?.State != HubConnectionState.Connected)
            {
                await hubConnection.StartAsync();
                if (hubConnection.State == HubConnectionState.Connected)
                {
                    // 重新加载数据
                    await LoadConversations();
                    if (SelectedConversation != null)
                    {
                        await hubConnection.SendAsync("JoinConversation", SelectedConversation.Id);
                        await hubConnection.SendAsync("GetMessageHistory", SelectedConversation.Id);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"尝试重连失败: {ex.Message}");
        }
    }

    private class UserInfo
    {
        public string UserId { get; set; }
        public string UserName { get; set; }
    }
} 